home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
bsvc-1.000
/
bsvc-1
/
bsvc-1.0.4
/
src
/
Assemblers
/
hecasm
/
asm4.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-26
|
5KB
|
215 lines
/*
File: asm4.c
Purpose: Parse the instruction operands: data operands and branch operands.
*/
#include "asm.h"
/*-----------------------------------------------------------------------
getmode:
Parse the operand field of an instruction.
*/
struct d_operand getmode()
{
int c;
char word[50];
char *last_index;
struct sym *kp;
struct d_operand operand;
operand.parse_error = 0;
c = getnb();
switch (c)
{ case '#': /* Immediate: */
operand.mode = AM_IP;
operand.mode_bits = 0x2;
operand.reg = 15;
operand.ext_word = expr();
break;
case '[': /* Indirect, Indirect w/inc, indexed: */
c = getnb();
getid(c,word);
kp = pstlookup(word);
/* Symbol not found: */
if ((kp==NULL) || (kp->s_type!=GR_REG))
{ err('R',"Expecting register");
operand.parse_error = 1;
}
else
{ operand.reg = kp->s_value; /* operating register */
c = getnb();
if (c==']') /* Indirect: close braket */
{ operand.mode = AM_IN;
operand.mode_bits = 0x1;
}
else if (c=='+') /* Indirect w/inc: + sign */
{ operand.mode = AM_IP;
operand.mode_bits = 0x2;
c = getnb();
if (c!=']') /* Closing ] */
{ err(']',"brace imbalance");
operand.parse_error = 1;
}
}
else if (c==',') /* Indexed: delimiting comma */
{ operand.mode = AM_IX;
operand.mode_bits = 0x3;
operand.ext_word = expr();
c = getnb();
if (c!=']') /* Closing ] */
{ err(']',"brace imbalance");
operand.parse_error = 1;
}
}
else /* Syntax error */
operand.parse_error = 1;
}
break;
default: /* Register or PC relative */
putback(c);
last_index = sptr; /* Remember current char index */
c = getnb();
getid(c,word);
kp = pstlookup(word);
if ((kp!=NULL) && (kp->s_type==GR_REG)) /* Register */
{ operand.mode = AM_RD;
operand.mode_bits = 0x0;
operand.reg = kp->s_value;
}
else /* PC Relative */
/* For PC relative, we should let the caller calc. the actual
offset. This avoids offset misalignments. */
{ sptr = last_index;
operand.mode = AM_IX;
operand.mode_bits = 0x3;
operand.reg = 15;
operand.ext_word = expr(); /* Get absolute address */
}
break;
}/* end switch */
return (operand);
}
/*
getbmode:
Parse the instruction operand field for the branch target.
*/
struct d_operand getbmode()
{
int c;
char word[50];
char *last_index;
struct sym *kp;
struct d_operand operand;
operand.parse_error = 0;
c = getnb();
switch (c)
{ case '@': /* Absolute */
operand.mode = BM_A;
operand.mode_bits = 0x1;
operand.reg = 0;
operand.ext_word = expr();
break;
case '[': /* Indexed */
operand.mode = BM_I;
operand.mode_bits = 0x3;
c = getnb();
getid(c,word);
kp = pstlookup(word);
/* Symbol not found: */
if ((kp==NULL) || (kp->s_type!=GR_REG))
{ err('R',"Expecting register");
operand.parse_error = 1;
}
else
{ operand.reg = kp->s_value; /* operating register */
c = getnb();
if (c==',') /* Indexed: delimiting comma */
{ operand.ext_word = expr();
c = getnb();
if (c!=']') /* Closing ] */
{ err(']',"brace imbalance");
operand.parse_error = 1;
}
}
else /* Syntax error */
{ err(',',"expecting comma");
operand.parse_error = 1;
}
}
break;
default: /* Register or Relative */
putback(c);
last_index = sptr; /* Remember current char index */
c = getnb();
getid(c,word);
kp = pstlookup(word);
if ((kp!=NULL) && (kp->s_type==GR_REG)) /* Register */
{ operand.mode = BM_R;
operand.mode_bits = 0x0;
operand.reg = kp->s_value;
}
else /* PC Relative */
/* For PC relative, we should let the caller calc. the actual
offset. This avoids offset misalignments. */
{ sptr = last_index;
operand.mode = BM_L;
operand.mode_bits = 0x2;
operand.reg = 0;
operand.ext_word = expr(); /* Get absolute address */
}
break;
}/* end switch */
return (operand);
}
/*
getcc:
Parse the condition codes.
*/
struct b_operand getcc()
{
int c;
char word[50];
struct sym *kp;
struct b_operand operand;
operand.parse_error = 0;
c = getnb();
getid(c,word);
kp = pstlookup(word);
/* Branch condition code not found: */
if ((kp==NULL) || (kp->s_type!=GR_CC))
{ err('c',"expecting condition code");
operand.parse_error = 1;
}
else
operand.mode_bits = kp->s_value;
return (operand);
}